import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
import express = require('express');
import { ProxyService } from './proxyService';

// 配置接口
interface LoginConfig {
  loginPort: number;
}

// 用户信息接口
interface UserInfo {
  cnName: string;
  userId: string;
  email?: string;
}

// 登录回调接口
interface LoginCallback {
  onSuccess: (userInfo: UserInfo) => void;
  onFailure: (reason: string, message: string) => void;
}

export class LoginService {
  private static instance: LoginService;
  private config: LoginConfig;
  private context: vscode.ExtensionContext;
  private httpServer: any = null;
  private isServerRunning: boolean = false;
  private loginCallback: LoginCallback | null = null;
  private readonly _onDidLoginStatusChange = new vscode.EventEmitter<void>();
  public readonly onDidLoginStatusChange = this._onDidLoginStatusChange.event;

  private constructor(context: vscode.ExtensionContext) {
    // 默认配置
    this.config = {
      loginPort: 31999
    };
    this.context = context;
  }

  public static getInstance(context: vscode.ExtensionContext): LoginService {
    if (!LoginService.instance) {
      LoginService.instance = new LoginService(context);
    }
    return LoginService.instance;
  }

  /**
   * 检查用户是否已登录
   */
  public async isLoggedIn(): Promise<boolean> {
    try {
      const userInfo = await this.getUserInfo();
      return !!userInfo;
    } catch (error) {
      console.error('检查登录状态失败:', error);
      // 如果 cookie 无效，删除它
      await this.clearCookie();
      return false;
    }
  }

  /**
   * 获取用户信息
   */
  public async getUserInfo(): Promise<UserInfo | null> {
    try {
      const result = await ProxyService.getInstance(this.context).post<UserInfo>('/api/user/getUser');
      
      if (result.success && result.data) {
        return {
          cnName: result.data.cnName,
          userId: result.data.userId,
          email: result.data.email
        };
      }

      return null;
    } catch (error) {
      console.error('获取用户信息失败:', error);
      return null;
    }
  }

  /**
   * 启动登录
   */
  public async startLogin(callback?: LoginCallback): Promise<void> {
    try {
      // 设置回调函数
      this.loginCallback = callback || null;
      
      // 启动本地 HTTP 服务器
      await this.startHttpServer();
      
      // 获取登录 URL
      const result = await ProxyService.getInstance(this.context).getLoginUrl();
      
      if (!result.success || !result.data?.loginUrl) {
        throw new Error('获取登录URL失败');
      }

      const loginUrl = result.data.loginUrl;
      const localLoginUrl = `${process.env.LOCAL_LOGIN_URL}/index?loginUrl=${loginUrl}`;
      
      // 打开浏览器进行登录
      vscode.env.openExternal(vscode.Uri.parse(localLoginUrl));
      
      vscode.window.showInformationMessage('正在打开浏览器进行登录...');
    } catch (error) {
      console.error('启动登录失败:', error);
      const errorMessage = `启动登录失败: ${error}`;
      vscode.window.showErrorMessage(errorMessage);
      
      // 如果有回调，通知失败
      if (this.loginCallback) {
        this.loginCallback.onFailure('startup_error', errorMessage);
        this.loginCallback = null;
      }
    }
  }

  /**
   * 启动 HTTP 服务器
   */
  private async startHttpServer(): Promise<void> {
    if (this.isServerRunning) {
      return;
    }

    return new Promise((resolve, reject) => {
      try {
        const app = express();
        
        // 处理登录回调
        app.get('/login', async (req: any, res: any) => {
          res.setHeader('Content-Type', 'text/html');
          
          if (req.query.code) {
            try {
              const response = await ProxyService.getInstance(this.context).get(`/api/validate/login/gitee?code=${req.query.code}`);
              const setCookieHeader = response.headers["set-cookie"];
              
              if (!setCookieHeader || setCookieHeader.length === 0) {
                throw new Error('未收到登录凭证');
              }
              
              const cookie = setCookieHeader[0];
              
              // 保存 cookie 到 secureStorage
              await this.saveCookie(cookie);
              
              // 获取用户信息
              const userInfo = await this.getUserInfo();
              
              if (userInfo) {
                // 发送成功页面
                const successHtml = this.getLoginSuccessHtml(userInfo.cnName);
                res.send(successHtml);
                
                // 通知登录成功
                vscode.window.showInformationMessage(`登录成功，欢迎 ${userInfo.cnName}！`);
                this.fireLoginStatusChange();
                
                // 如果有回调，通知成功
                if (this.loginCallback) {
                  this.loginCallback.onSuccess(userInfo);
                  this.loginCallback = null;
                }
              } else {
                throw new Error('获取用户信息失败');
              }
            } catch (error) {
              console.error('登录验证失败:', error);
              const failedHtml = this.getLoginFailedHtml();
              res.send(failedHtml);
              
              // 如果有回调，通知失败
              if (this.loginCallback) {
                this.loginCallback.onFailure('validation_error', `登录验证失败: ${error}`);
                this.loginCallback = null;
              }
            }
          } else {
            const failedHtml = this.getLoginFailedHtml();
            res.send(failedHtml);
            
            // 如果有回调，通知失败
            if (this.loginCallback) {
              this.loginCallback.onFailure('no_code', '未收到授权码');
              this.loginCallback = null;
            }
          }
        });

        // 处理登录页面
        app.get('/index', (req: any, res: any) => {
          const loginHtml = this.getLoginHtml();
          res.send(loginHtml);
        });

        this.httpServer = app.listen(this.config.loginPort, () => {
          console.log(`登录服务器启动在端口 ${this.config.loginPort}`);
          this.isServerRunning = true;
          resolve();
        });

        this.httpServer.on('error', (error: any) => {
          console.error('HTTP 服务器启动失败:', error);
          reject(error);
        });

      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 停止 HTTP 服务器
   */
  private stopHttpServer(): void {
    if (this.httpServer && this.isServerRunning) {
      this.httpServer.close();
      this.httpServer = null;
      this.isServerRunning = false;
      console.log('登录服务器已停止');
    }
  }

  /**
   * 登出
   */
  public async logout(): Promise<void> {
    try {
      // 删除 cookie
      await this.clearCookie();
      
      // 停止 HTTP 服务器
      this.stopHttpServer();
      
      vscode.window.showInformationMessage('已成功登出');
      this.fireLoginStatusChange();
    } catch (error) {
      console.error('登出失败:', error);
      vscode.window.showErrorMessage(`登出失败: ${error}`);
    }
  }

  /**
   * 检查登录状态并处理超时
   */
  public async validateSession(): Promise<boolean> {
    try {
      const isValid = await this.isLoggedIn();
      
      if (!isValid) {
        await this.logout();
        
        // 显示带登录按钮的警告消息
        const selection = await vscode.window.showWarningMessage(
          '登录信息已过期，请重新登录',
          '登录'
        );
        
        // 如果用户点击了登录按钮
        if (selection === '登录') {
          try {
            await this.startLogin({
              onSuccess: (userInfo) => {
                vscode.window.showInformationMessage(`登录成功，欢迎 ${userInfo.cnName}！`);
              },
              onFailure: (reason, errorMessage) => {
                vscode.window.showErrorMessage(`登录失败: ${errorMessage}`);
              }
            });
          } catch (error) {
            console.error('启动登录失败:', error);
            vscode.window.showErrorMessage('启动登录失败，请稍后重试');
          }
        }
      }
      
      return isValid;
    } catch (error) {
      console.error('验证会话失败:', error);
      return false;
    }
  }

  /**
   * 获取登录页面 HTML
   */
  private getLoginHtml(): string {
    try {
      const htmlPath = path.join(__dirname, '../resource/html/login.html');
      return fs.readFileSync(htmlPath, 'utf-8');
    } catch (error) {
      console.error('读取登录页面失败:', error);
      // 如果读取失败，返回简单的错误页面
      return '<html><body><h1>登录页面加载失败</h1></body></html>';
    }
  }

  /**
   * 获取登录成功页面 HTML
   */
  private getLoginSuccessHtml(userName: string): string {
    try {
      const htmlPath = path.join(__dirname, '../resource/html/loginSuccess.html');
      const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
      // 替换用户名占位符
      return htmlContent.replace('{name}', userName);
    } catch (error) {
      console.error('读取登录成功页面失败:', error);
      // 如果读取失败，返回简单的成功页面
      return `<html><body><h1>登录成功</h1><p>欢迎 ${userName}！</p></body></html>`;
    }
  }

  /**
   * 获取登录失败页面 HTML
   */
  private getLoginFailedHtml(): string {
    try {
      const htmlPath = path.join(__dirname, '../resource/html/loginFailed.html');
      return fs.readFileSync(htmlPath, 'utf-8');
    } catch (error) {
      console.error('读取登录失败页面失败:', error);
      // 如果读取失败，返回简单的错误页面
      return '<html><body><h1>登录失败</h1><p>登录过程中出现错误，请重试</p></body></html>';
    }
  }

  /**
   * 获取当前 Cookie
   */
  public async getCookie(): Promise<string | null> {
    try {
      if (!this.context) {
        console.warn('ExtensionContext not available for secureStorage');
        return null;
      }
      const cookie = await this.context.secrets.get('harmonypilot.cookie');
      return cookie || null;
    } catch (error) {
      console.error('读取 Cookie 失败:', error);
      return null;
    }
  }

  /**
   * 保存 Cookie 到 secureStorage
   */
  private async saveCookie(cookie: string): Promise<void> {
    try {
      if (!this.context) {
        console.warn('ExtensionContext not available for secureStorage');
        return;
      }
      await this.context.secrets.store('harmonypilot.cookie', cookie);
    } catch (error) {
      console.error('保存 Cookie 失败:', error);
    }
  }

  /**
   * 清理 Cookie
   */
  private async clearCookie(): Promise<void> {
    try {
      if (!this.context) {
        console.warn('ExtensionContext not available for secureStorage');
        return;
      }
      await this.context.secrets.delete('harmonypilot.cookie');
    } catch (error) {
      console.error('清理 Cookie 失败:', error);
    }
  }

  /**
   * 触发登录状态变化事件
   */
  public fireLoginStatusChange(): void {
    this._onDidLoginStatusChange.fire();
  }

  /**
   * 清理资源
   */
  public dispose(): void {
    this.stopHttpServer();
    this._onDidLoginStatusChange.dispose();
  }
}
